package com.tqjc.system.core.pipeline.util;

import cn.hutool.core.collection.CollUtil;
import com.tqjc.system.common.constant.AddTaskConstant;
import com.tqjc.system.common.constant.ConfigConstant;
import com.tqjc.system.common.constant.GlobalConstant;
import com.tqjc.system.common.constant.RemoteURLConstant;
import com.tqjc.system.common.entity.BO.MaterialSpanBO;
import com.tqjc.system.common.entity.BO.ResponseLabelDataBO;
import com.tqjc.system.common.entity.BO.TaskMaterialBO;
import com.tqjc.system.common.enums.CarEnum;
import com.tqjc.system.common.enums.CarPLCInfoEnum;
import com.tqjc.system.common.enums.SpanEnum;
import com.tqjc.system.common.exception.AddTaskException;
import com.tqjc.system.core.pipeline.thread.AbstrCarDoingAddTaskThread;
import com.tqjc.system.core.util.PLCHttpsUtils;
import com.tqjc.system.system.util.SystemUtils;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author 86195
 * @version 1.0
 * @description 加料任务工具类
 * @date 2023/10/17 11:47
 */
@Slf4j
public class AddTaskUtil {

    //天车状态跨锁
    private static final String spanLock = "spanLock";

    //天车目标坐标锁
//    private static final String carIndexLock = "carIndexLock";

    //天车目标坐标锁
    private static final ReentrantLock carIndexLock = new ReentrantLock();


    //缓存当前工作跨物料集合   key:taskid   value:workingMaterialList
    public static final Map<String, List<TaskMaterialBO>> TASK_WORKING_MATERIAL_MAP = new HashMap<>(3);



    //天车物料集合锁
    private static final String materialListLock = "materialListLock";

    private static final Map<String,String> threadMap = new HashMap(2){{
        put(AddTaskConstant.WASTE_STEEL_SPAN_NO,"1");
        put(AddTaskConstant.DREGS_STEEL_SPAN_NO,"1");
    }};

    /**
     * 是否需要生成被动的唤醒线程   false:不需要   true:需要
     * @param spanNo
     * @return
     */
    public static boolean isPassiveThread(String spanNo){
        String s = threadMap.get(spanNo);
        if(s == null){
            log.info("当前天车不需要生成唤醒线程");
            return false;
        }
        threadMap.remove(spanNo);
        log.info("当前天车需要生成唤醒线程");
        return true;

    }

    public static void giveBackThread(String spanNo){
        threadMap.put(spanNo,"1");
    }



    public static MaterialSpanBO getFreeSpan(){
        synchronized (spanLock){
            for (SpanEnum value : SpanEnum.values()) {
                MaterialSpanBO materialSpanBO = AddTaskConstant.SPAN_MAP.get(value.getSpanNo());
                if(AddTaskConstant.SPAN_STATUS_FREE.equals(materialSpanBO.getStatus())){
                    return materialSpanBO;
                }
            }
        }
        return null;
    }


    public static MaterialSpanBO getFreeSpan(String spanNo){
        synchronized (spanLock){
            MaterialSpanBO materialSpanBO = AddTaskConstant.SPAN_MAP.get(spanNo);
            if(AddTaskConstant.SPAN_STATUS_FREE.equals(materialSpanBO.getStatus())){
                return materialSpanBO;
            }
        }
        return null;
    }


    public static void updateSpanNoStatus(String spanNo,String status){
        synchronized (spanLock){
            MaterialSpanBO materialSpanBO = AddTaskConstant.SPAN_MAP.get(spanNo);
            materialSpanBO.setStatus(status);
            AddTaskConstant.SPAN_MAP.put(spanNo,materialSpanBO);
        }

    }

    /***
     *
     * @param key  key组成：跨区编号 + "_" + 天车编号
     * @param index
     */
    public static void updateCarIndex(String key,Integer index){
        carIndexLock.lock();
        AddTaskConstant.CAR_TARGET_INDEX_MAP.put(key,index);
        carIndexLock.unlock();
    }

    /**
     *
     * @param key   组成规则：spanNo +_ + carNo
     * @return
     */
    public static Integer getCarIndex(String key){

        carIndexLock.lock();
        Integer integer = AddTaskConstant.CAR_TARGET_INDEX_MAP.get(key);
        carIndexLock.unlock();

        return integer;
    }


    public static boolean isConflict(String workCarKey,String otherCarKey,CarEnum workingCar){

        try {

            carIndexLock.lock();
            int targetIndex = AddTaskConstant.CAR_TARGET_INDEX_MAP.get(workCarKey);
            Integer otherIndex = AddTaskConstant.CAR_TARGET_INDEX_MAP.get(otherCarKey);
            return comparePosition(workingCar,targetIndex,otherIndex);
        } catch (Exception e){
            log.error("AddTaskUtil.isConflict方法  run error",e);
        } finally {
            carIndexLock.unlock();
        }
        return false;

    }


    public static TaskMaterialBO getTaskMaterial(String taskId, CarEnum carEnum){
        synchronized (materialListLock){
            List<TaskMaterialBO> list = AddTaskUtil.TASK_WORKING_MATERIAL_MAP.get(taskId);
            if(CollUtil.isNotEmpty(list)){
                TaskMaterialBO res = carEnum.getCarNo().equals(CarEnum.CAR_NO_1.getCarNo()) ? list.get(list.size() -1):list.get(0);
                list.removeIf( e -> e.equals(res));
                return res;
            }
        }
        return null;
    }


    /**
     * 判断辆车的目标位置是否冲突
     * @param curCar
     * @param curPosition
     * @param otherPosition
     * @return  true:没有冲突   false：有冲突
     */
    private static boolean comparePosition(CarEnum curCar, int curPosition, Integer otherPosition){
        int i = AddTaskConstant.SAFE_DISTANCE;
        if(otherPosition == null){
            //空值代表暂时没有移动，另一台车在安全位置
            return true;
        }


        if(curPosition == 0){
            //空值代表暂时没有移动，另一台车在安全位置
            return true;
        }
        if(curCar.getCarNo() == CarEnum.CAR_NO_1.getCarNo()){
            //代表当前天车为右侧天车
            if(curPosition > otherPosition &&  curPosition - otherPosition >= i){
                return true;
            }
            return false;
        } else {
            //代表当前天车为左侧天车
            if(curPosition < otherPosition &&  otherPosition - curPosition >= i){
                return true;
            }
            return false;
        }
    }


    /**
     * 判断天车是否处理运行状态   ture:两台车可以运行，可以发指令   false：不可以发指令
     * @return
     */
    public static boolean isCarRunningStatus(String sn,String carNO1MacSN,String carNO2MacSN){
        Map map = new HashMap(2);
        map.put(GlobalConstant.STRING_SN,sn);
        map.put(GlobalConstant.STRING_LABEL,carNO1MacSN + GlobalConstant.CAR_RUNNING_LABEL);
        Map<String, String> snMap = SystemUtils.Sys_carInfo.get(ConfigConstant.CONFIG_TYPE_CAR_BAK_SN);
        String carNO2sn = snMap.get(carNO2MacSN);
        int i = 0;
        try {

            while (true){
                if(i >= 3){
                    log.error("查看双车行车状态是否为自动时，循环次数超过三次");
                    break;
                }
                ResponseLabelDataBO carNO1DataBO = PLCHttpsUtils.sendPost(RemoteURLConstant.URL_READBC, map, ResponseLabelDataBO.class);
                Map<String, String> carNO1content = carNO1DataBO.getContent();
                boolean carNO1Flag = carNO1content != null ? Boolean.valueOf(carNO1content.get("currentVal")) : false;
                map.put(GlobalConstant.STRING_SN,carNO2sn);
                map.put(GlobalConstant.STRING_LABEL,carNO2MacSN + GlobalConstant.CAR_RUNNING_LABEL);
                ResponseLabelDataBO carNO2DataBO = PLCHttpsUtils.sendPost(RemoteURLConstant.URL_READBC, map, ResponseLabelDataBO.class);
                Map<String, String> carNO2Content = carNO2DataBO.getContent();
                boolean carNO2Flag = carNO2Content != null ? Boolean.valueOf(carNO2Content.get("currentVal")) : false;

                if(carNO1Flag && carNO2Flag){
                    return true;
                }
                Thread.sleep(5*1000);

            }
        } catch (Exception e){
            log.error("加料工具类判断双车是否可运行状态出错",e);
        }

        return false;

    }









}
